package wangjg.commons.io;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

/**
 * @author wangjg
 * 
 * 根据文件头判文件类型
 */
public class FileHeaderHelper {
	private final static Hashtable<String,String> headers;
	static{
		headers = new Hashtable<String,String>();
		headers.put("FFD8FF", "jpg");
		headers.put("89504E47", "png");
		headers.put("47494638", "gif");
		headers.put("49492A00", "tif");
		headers.put("424D", "bmp");
		headers.put("49443304", "mp3");
	}
	
	private final static Hashtable<String,String> mediaTypes;
	static{
		mediaTypes = new Hashtable<String,String>();
		mediaTypes.put("mp3", "audio/mpeg");
		mediaTypes.put("jpg", "image/jpeg");
		mediaTypes.put("gif", "image/gif");
		mediaTypes.put("png", "image/png");
	}
	
	public static String getMediaType(String extName){
		return mediaTypes.get(extName);
	}
	
	public static String getExtName(String filepath) throws IOException{
		FileInputStream fis = new FileInputStream(filepath);
		try{
			return getExtName(fis);
		}finally{
			if(fis!=null)fis.close();
		}
	}
	
	public static String getExtName(InputStream is) throws IOException{
		byte[] buf = new byte[8];
		int size = is.read(buf);
		return getExtName(buf);
	}
	
	public static String getExtName(byte[] head) throws IOException{
		String str = bytesToHexString(head);
		if(str!=null){
			str=str.toUpperCase();
			Set<Entry<String, String>> entrySet = headers.entrySet();   
			for (Map.Entry<String, String> entry : entrySet) {
			    String name=entry.getKey();
			    String value=entry.getValue();
			    if(str.startsWith(name)){
			    	return value;
			    }
			}
		}
		return null;
	}
	
	public static void main(String args[]) throws IOException{
		FileHeaderHelper h=new FileHeaderHelper();
		System.out.println(h.getExtName("D:\\mm.jpg"));
	}
	
	/** 
	 * Convert byte[] to hex string.这里我们可以将byte转换成int，然后利用Integer.toHexString(int)来转换成16进制字符串。 
	 * @param src byte[] data 
	 * @return hex string 
	 */     
	private static String bytesToHexString(byte[] src){  
	    StringBuilder stringBuilder = new StringBuilder("");  
	    if (src == null || src.length <= 0) {  
	        return null;  
	    }  
	    for (int i = 0; i < src.length; i++) {  
	        int v = src[i] & 0xFF;  
	        String hv = Integer.toHexString(v);  
	        if (hv.length() < 2) {  
	            stringBuilder.append(0);  
	        }  
	        stringBuilder.append(hv);  
	    }  
	    return stringBuilder.toString();  
	}  
	/** 
	 * Convert hex string to byte[] 
	 * @param hexString the hex string 
	 * @return byte[] 
	 */  
	private static byte[] hexStringToBytes(String hexString) {  
	    if (hexString == null || hexString.equals("")) {  
	        return null;  
	    }  
	    hexString = hexString.toUpperCase();  
	    int length = hexString.length() / 2;  
	    char[] hexChars = hexString.toCharArray();  
	    byte[] d = new byte[length];  
	    for (int i = 0; i < length; i++) {  
	        int pos = i * 2;  
	        d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));  
	    }  
	    return d;  
	}  
	/** 
	 * Convert char to byte 
	 * @param c char 
	 * @return byte 
	 */  
	 private static byte charToByte(char c) {  
	    return (byte) "0123456789ABCDEF".indexOf(c);  
	}  
}
